package io.gitee.zhangbinhub.admin.log.bus.listener

import io.gitee.zhangbinhub.acp.boot.http.HttpStatus
import io.gitee.zhangbinhub.acp.boot.log.LogAdapter
import io.gitee.zhangbinhub.acp.core.common.task.BaseAsyncTask
import io.gitee.zhangbinhub.acp.core.common.task.threadpool.ThreadPoolService
import io.gitee.zhangbinhub.admin.common.base.BaseCloudEventHandler
import io.gitee.zhangbinhub.admin.common.constant.BusEventConstant
import io.gitee.zhangbinhub.admin.common.event.RouteLogBusEvent
import io.gitee.zhangbinhub.admin.log.conf.LogServerCustomerConfiguration
import io.gitee.zhangbinhub.admin.log.message.RouteLogMessage
import io.gitee.zhangbinhub.admin.log.service.LogService
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import org.noear.snack4.ONode
import org.noear.solon.cloud.annotation.CloudEvent

/**
 * @since JDK 11
 */
@CloudEvent(BusEventConstant.ROUTE_LOG_BUS_EVENT_TOPIC)
class RouteLogEventListener(
    private val logAdapter: LogAdapter,
    private val logService: LogService,
    private val logServerCustomerConfiguration: LogServerCustomerConfiguration
) : BaseCloudEventHandler(logAdapter) {
    override fun doHandle(routeLogBusEvent: RouteLogBusEvent) {
        ThreadPoolService.getInstance(1, 1, Int.MAX_VALUE).addTask(object : BaseAsyncTask("route_log", false) {
            override fun beforeExecuteFun(): Boolean = true
            override fun executeFun(): Any {
                val message = routeLogBusEvent.content.message
                logAdapter.debug("收到日志消息：$message")
                try {
                    ONode.deserialize<RouteLogMessage>(message, RouteLogMessage::class.java)?.also {
                        runBlocking {
                            if (logServerCustomerConfiguration.routeLogEnabled) {
                                launch(Dispatchers.IO) {
                                    logService.doRouteLog(message)
                                }
                            }
                            it.token?.apply {
                                if (logServerCustomerConfiguration.operateLogEnabled) {
                                    launch(Dispatchers.IO) {
                                        logService.doOperateLog(message)
                                    }
                                }
                                if (it.responseStatus == HttpStatus.OK.value()) {
                                    if (it.applyToken) {
                                        launch(Dispatchers.IO) {
                                            logService.doLoginLog(message)
                                        }
                                    }
                                }
                            }
                        }
                    }
                } catch (e: Exception) {
                    logAdapter.error("日志消息：$message \n处理失败：${e.message}", e)
                }
                return true
            }

            override fun afterExecuteFun(result: Any) {}
        })
    }
}